package com.af.financeomine.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository("com.af.financeomine.dao.Dao")
public class DaoImpl<T> implements Dao<T> {
	
	private static Logger log = Logger.getLogger(DaoImpl.class);

	protected EntityManager em;
	protected Class<T> classe;

	public DaoImpl() {
		log.info("Call default Constructor");
	}

	public DaoImpl(Class<T> classe) {
		log.info("Call Constructor, Parameters: " + classe.getName());
		this.classe = classe;
	}

	@PersistenceContext
	public void setEntityManager(EntityManager em) {
		log.debug("Call setEntityManager, " + em); 
		this.em = em;
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false) 
	public void delete(T t) {
		log.debug("Call delete, " + t.toString());
		em.remove(t);
	} 

	public T findById(Long id) {
		log.debug("Call findById, id: " + id); 
		return em.find(classe, id);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> listAll() {
		log.debug("Call listAll");
		Query q = em.createQuery("select e from " + classe.getName() + " e");
		return q.getResultList();
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false)
	public void save(T t) {
		log.debug("Call save, " + t.toString());
		em.persist(t);
	}

	@Transactional
	public T update(T t) {
		log.debug("Call update, " + t.toString());
		return em.merge(t);
	}

	public void setClasse(Class<T> classe) {
		log.debug("Call setClasse, " + classe.getName());
		this.classe = classe;
	}
}
